package xyz.wbsite.zentao.sdk.project;

import cn.hutool.core.convert.Convert;
import cn.hutool.core.util.NumberUtil;
import cn.hutool.core.util.RandomUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.http.HttpException;
import cn.hutool.http.HttpRequest;
import cn.hutool.http.HttpResponse;
import cn.hutool.http.HttpStatus;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import cn.hutool.log.StaticLog;
import xyz.wbsite.zentao.sdk.Constant;
import xyz.wbsite.zentao.sdk.ZentaoInstance;
import xyz.wbsite.zentao.sdk.project.ent.ZtProject;
import xyz.wbsite.zentao.sdk.project.req.ZtProjectActivateRequest;
import xyz.wbsite.zentao.sdk.project.req.ZtProjectCloseRequest;
import xyz.wbsite.zentao.sdk.project.req.ZtProjectCreateRequest;
import xyz.wbsite.zentao.sdk.project.req.ZtProjectDeleteRequest;
import xyz.wbsite.zentao.sdk.project.req.ZtProjectEditRequest;
import xyz.wbsite.zentao.sdk.project.req.ZtProjectStartRequest;
import xyz.wbsite.zentao.sdk.project.rsp.ZtProjectActivateResponse;
import xyz.wbsite.zentao.sdk.project.rsp.ZtProjectCloseResponse;
import xyz.wbsite.zentao.sdk.project.rsp.ZtProjectCreateResponse;
import xyz.wbsite.zentao.sdk.project.rsp.ZtProjectDeleteResponse;
import xyz.wbsite.zentao.sdk.project.rsp.ZtProjectEditResponse;
import xyz.wbsite.zentao.sdk.project.rsp.ZtProjectGetResponse;
import xyz.wbsite.zentao.sdk.project.rsp.ZtProjectStartResponse;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;

/**
 * 禅道项目接口服务
 *
 * @author wangbing
 * @version 0.0.1
 * @since 1.8
 */
public class ZtProjectService {

    private ZentaoInstance zentaoInstance;

    public ZtProjectService(ZentaoInstance zentaoInstance) {
        this.zentaoInstance = zentaoInstance;
    }

    /**
     * 创建项目
     */
    public ZtProjectCreateResponse create(ZtProjectCreateRequest request) {
        ZtProjectCreateResponse response = new ZtProjectCreateResponse();
        try {
            String url = StrUtil.format("/project-create-{}-0-0-productID=0,branchID=0.json", request.getModel());
            StaticLog.info(url);
            HttpRequest httpRequest = zentaoInstance.createPost(url);
            httpRequest.contentType("application/x-www-form-urlencoded; charset=UTF-8");
            httpRequest.form("parent", request.getParent());
            httpRequest.form("name", request.getName());
            httpRequest.form("code", request.getCode());
            httpRequest.form("multiple", request.getMultiple());
            httpRequest.form("hasProduct", request.getHasProduct());
            httpRequest.form("PM", request.getPm());
            httpRequest.form("budget", NumberUtil.decimalFormat("#.00", Convert.toDouble(request.getBudget(), 0D)));
            httpRequest.form("budgetUnit", request.getBudgetUnit());
            httpRequest.form("begin", request.getBegin());
            httpRequest.form("end", request.getEnd());
            httpRequest.form("days", request.getDays());
            httpRequest.form("products[0]", request.getProducts());
            httpRequest.form("productName", request.getProductName());
            httpRequest.form("desc", request.getDesc());
            httpRequest.form("acl", request.getAcl());
            httpRequest.form("auth", request.getAuth());
            httpRequest.form("model", request.getModel());
            httpRequest.form("uid", RandomUtil.randomString(13));

            HttpResponse execute = httpRequest.execute();
            if (HttpStatus.HTTP_OK != execute.getStatus()) {
                response.setSuccess(false);
                response.setMessage("请求失败");
                return response;
            }
            String body = Convert.unicodeToStr(execute.body());
            //{"result":"success","message":"保存成功","id":"355"}
            StaticLog.info(body);
            if (body.contains(Constant.SUCCESS_KEY)) {
                JSONObject entries = JSONUtil.parseObj(body);
                response.setId(Convert.toInt(entries.get("id")));
                response.setSuccess(true);
                response.setMessage("请求成功");
                return response;
            }
        } catch (HttpException e) {
            throw new RuntimeException(e);
        }
        response.setSuccess(false);
        response.setMessage("请求失败");
        return response;
    }

    /**
     * 更新项目
     */
    public ZtProjectEditResponse edit(ZtProjectEditRequest request) {
        ZtProjectEditResponse response = new ZtProjectEditResponse();
        try {
            String url = StrUtil.format("/project-edit-{}-view.json", request.getId());
            StaticLog.info(url);
            HttpRequest httpRequest = zentaoInstance.createPostForHtml(url);
            httpRequest.form("parent", request.getParent());
            httpRequest.form("name", request.getName());
            httpRequest.form("code", request.getCode());
            httpRequest.form("PM", request.getPm());
            httpRequest.form("budget", NumberUtil.decimalFormat("#.00", Convert.toDouble(request.getBudget(), 0D)));
            httpRequest.form("budgetUnit", request.getBudgetUnit());
            httpRequest.form("future", request);
            httpRequest.form("begin", request.getBegin());
            httpRequest.form("end", request.getEnd());
            httpRequest.form("days", request.getDays());
            httpRequest.form("desc", request.getDesc());
            httpRequest.form("acl", request.getAcl());
            httpRequest.form("auth", request.getAuth());
            httpRequest.form("model", request.getModel());
            httpRequest.form("delta", request.getDelta());
            httpRequest.form("uid", RandomUtil.randomString(13));
            HttpResponse execute = httpRequest.execute();
            if (HttpStatus.HTTP_OK != execute.getStatus()) {
                response.setSuccess(false);
                response.setMessage("请求失败");
                return response;
            }
            String body = Convert.unicodeToStr(execute.body());
            //{"result":"success","message":"保存成功","locate":"/project-view-363.json"}
            StaticLog.info(body);
            if (body.contains(Constant.SUCCESS_KEY)) {
                response.setSuccess(true);
                response.setMessage("请求成功");
                return response;
            }
        } catch (Exception e) {
            StaticLog.error(e);
        }
        response.setSuccess(false);
        response.setMessage("请求失败");
        return response;
    }

    /**
     * 启动项目
     */
    public ZtProjectStartResponse start(ZtProjectStartRequest request) {
        ZtProjectStartResponse response = new ZtProjectStartResponse();
        try {
            String url = StrUtil.format("/project-start-{}.html", request.getProjectId());
            StaticLog.info(url);
            HttpRequest httpRequest = zentaoInstance.createPost(url);
            httpRequest.form("status", "doing");
            httpRequest.form("realBegan", request.getRealBegan());
            httpRequest.form("comment", request.getComment());
            httpRequest.form("uid", RandomUtil.randomString(13));
            HttpResponse execute = httpRequest.execute();
            if (HttpStatus.HTTP_OK != execute.getStatus()) {
                response.setSuccess(false);
                response.setMessage("请求失败");
                return response;
            }
            String body = Convert.unicodeToStr(execute.body());
            StaticLog.info(body);
            response.setSuccess(true);
            response.setMessage("请求成功");
            return response;
        } catch (Exception e) {
            StaticLog.error(e);
        }
        response.setSuccess(false);
        response.setMessage("请求失败");
        return response;
    }

    /**
     * 关闭项目
     */
    public ZtProjectCloseResponse close(ZtProjectCloseRequest request) {
        ZtProjectCloseResponse response = new ZtProjectCloseResponse();
        try {
            String url = StrUtil.format("/project-close-{}.html", request.getProjectId());
            StaticLog.info(url);
            HttpRequest httpRequest = zentaoInstance.createPost(url);
            httpRequest.form("status", "closed");
            httpRequest.form("realEnd", request.getRealEnd());
            httpRequest.form("comment", request.getComment());
            httpRequest.form("uid", RandomUtil.randomString(13));
            HttpResponse execute = httpRequest.execute();
            if (HttpStatus.HTTP_OK != execute.getStatus()) {
                response.setSuccess(false);
                response.setMessage("请求失败");
                return response;
            }
            String body = Convert.unicodeToStr(execute.body());
            StaticLog.info(body);
            response.setSuccess(true);
            response.setMessage("请求成功");
            return response;
        } catch (Exception e) {
            StaticLog.error(e);
        }
        response.setSuccess(false);
        response.setMessage("请求失败");
        return response;
    }

    /**
     * 激活项目
     */
    public ZtProjectActivateResponse activate(ZtProjectActivateRequest request) {
        ZtProjectActivateResponse response = new ZtProjectActivateResponse();
        try {
            String url = StrUtil.format("/project-close-{}.html", request.getProjectId());
            StaticLog.info(url);
            HttpRequest httpRequest = zentaoInstance.createPost(url);
            httpRequest.form("begin", request.getBegin());
            httpRequest.form("end", request.getEnd());
            httpRequest.form("readjustTime", request.getReadjustTime());
            httpRequest.form("status", "doing");
            httpRequest.form("comment", request.getComment());
            httpRequest.form("uid", RandomUtil.randomString(13));
            HttpResponse execute = httpRequest.execute();
            if (HttpStatus.HTTP_OK != execute.getStatus()) {
                response.setSuccess(false);
                response.setMessage("请求失败");
                return response;
            }
            String body = Convert.unicodeToStr(execute.body());
            StaticLog.info(body);
            response.setSuccess(true);
            response.setMessage("请求成功");
            return response;
        } catch (Exception e) {
            StaticLog.error(e);
        }
        response.setSuccess(false);
        response.setMessage("请求失败");
        return response;
    }

    /**
     * 删除项目
     */
    public ZtProjectDeleteResponse delete(ZtProjectDeleteRequest request) {
        ZtProjectDeleteResponse response = new ZtProjectDeleteResponse();
        try {
            String url = StrUtil.format("/project-delete-{}-yes-browse.html", request.getProjectId());
            StaticLog.info(url);
            HttpRequest httpRequest = zentaoInstance.createPost(url);
            HttpResponse execute = httpRequest.execute();
            if (HttpStatus.HTTP_OK != execute.getStatus()) {
                response.setSuccess(false);
                response.setMessage("请求失败");
                return response;
            }
            String body = Convert.unicodeToStr(execute.body());
            StaticLog.info(body);
            response.setSuccess(true);
            response.setMessage("请求成功");
            return response;
        } catch (Exception e) {
            StaticLog.error(e);
        }
        response.setSuccess(false);
        response.setMessage("请求失败");
        return response;
    }

    /**
     * 设置查询条件
     * <p>
     * 禅道查询条件是设置在session中的，所有查询之前先设置参数
     */
    private boolean setQuery(String fieldName, String fieldValue) {
        try {
            String url = StrUtil.format("/search-buildQuery.html");
            StaticLog.info(url);
            HttpRequest httpRequest = zentaoInstance.createPost(url);
            httpRequest.form("fieldname", "");
            httpRequest.form("fieldcode", "");
            httpRequest.form("fieldid", "");
            httpRequest.form("fieldmodel", "");
            httpRequest.form("fieldhasProduct", "");
            httpRequest.form("fieldparent", "0");
            httpRequest.form("fieldstatus", "");
            httpRequest.form("fielddesc", "");
            httpRequest.form("fieldPM", "");
            httpRequest.form("fieldopenedDate", "");
            httpRequest.form("fieldbegin", "");
            httpRequest.form("fieldend", "");
            httpRequest.form("fieldrealBegan", "");
            httpRequest.form("fieldrealEnd", "");
            httpRequest.form("fieldopenedBy", "");
            httpRequest.form("fieldclosedBy", "");
            httpRequest.form("fieldlastEditedDate", "");
            httpRequest.form("fieldclosedDate", "");
            httpRequest.form("andOr1", "AND");
            httpRequest.form("field1", fieldName);
            httpRequest.form("operator1", "=");
            httpRequest.form("value1", fieldValue);
            httpRequest.form("andOr2", "and");
            httpRequest.form("field2", "code");
            httpRequest.form("operator2", "=");
            httpRequest.form("value2", "");
            httpRequest.form("andOr3", "and");
            httpRequest.form("field3", "id");
            httpRequest.form("operator3", "=");
            httpRequest.form("value3", "");
            httpRequest.form("groupAndOr", "and");
            httpRequest.form("andOr4", "AND");
            httpRequest.form("field4", "model");
            httpRequest.form("operator4", "=");
            httpRequest.form("value4", "");
            httpRequest.form("andOr5", "and");
            httpRequest.form("field5", "hasProduct");
            httpRequest.form("operator5", "=");
            httpRequest.form("value5", "");
            httpRequest.form("andOr6", "and");
            httpRequest.form("field6", "parent");
            httpRequest.form("operator6", "=");
            httpRequest.form("value6", 0);
            httpRequest.form("module", "project");
            httpRequest.form("actionURL", "/project-browse-0-bySearch-myQueryID.html");
            httpRequest.form("groupItems", "3");
            httpRequest.form("formType", "lite");
            HttpResponse execute = httpRequest.execute();
            if (HttpStatus.HTTP_OK != execute.getStatus()) {
                return false;
            }
            String body = Convert.unicodeToStr(execute.body());
            StaticLog.info(body);
            return execute.getStatus() == HttpStatus.HTTP_OK;
        } catch (Exception e) {
            StaticLog.error(e);
        }
        return false;
    }

    /**
     * 通过项目名称获取项目
     */
    public ZtProjectGetResponse getByName(String name) {
        ZtProjectGetResponse response = new ZtProjectGetResponse();
        try {
            boolean setQuery = setQuery("name", name);
            if (!setQuery) {
                response.setSuccess(false);
                response.setMessage("设置查询参数失败");
                return response;
            }
            HttpRequest httpRequest = zentaoInstance.createGetForHtml("/project-browse-0-bySearch-myQueryID.html");
            HttpResponse execute = httpRequest.execute();
            if (HttpStatus.HTTP_OK != execute.getStatus()) {
                response.setSuccess(false);
                response.setMessage("请求失败");
                return response;
            }
            String body = execute.body();
            Document parse = Jsoup.parse(body);
            Elements trs = parse.select(".main-table .sortable tr");
            if (trs.size() == 1) {
                Element tr = trs.get(0);
                ZtProject ztProject = new ZtProject();
                ztProject.setId(Convert.toInt(tr.select(".c-id").text()));
                ztProject.setName(tr.select(".c-name").attr("title"));
                ztProject.setStatus(tr.select(".c-status").text());
                ztProject.setPm(tr.select(".c-PM").text());
                ztProject.setBudget(tr.select(".c-budget").text());
                ztProject.setBegin(tr.select(".c-begin").text());
                ztProject.setEnd(tr.select(".c-end").text());
                ztProject.setProgress(tr.select(".c-progress").text());
                response.setSuccess(true);
                response.setMessage("请求成功");
                response.setResult(ztProject);
                return response;
            }
            StaticLog.info(body);
            response.setMessage("无数据");
            return response;
        } catch (HttpException e) {
            StaticLog.error(e);
        }
        response.setSuccess(false);
        response.setMessage("请求失败");
        return response;
    }

    /**
     * 通过项目编码获取项目
     */
    public ZtProjectGetResponse getByCode(String code) {
        ZtProjectGetResponse response = new ZtProjectGetResponse();
        try {
            boolean setQuery = setQuery("code", code);
            if (!setQuery) {
                response.setSuccess(false);
                response.setMessage("设置查询参数失败");
                return response;
            }
            HttpRequest httpRequest = zentaoInstance.createGetForHtml("/project-browse-0-bySearch-myQueryID.html");
            HttpResponse execute = httpRequest.execute();
            if (HttpStatus.HTTP_OK != execute.getStatus()) {
                response.setSuccess(false);
                response.setMessage("请求失败");
                return response;
            }
            String body = execute.body();
            Document parse = Jsoup.parse(body);
            Elements trs = parse.select(".main-table .sortable tr");
            if (trs.size() == 1) {
                Element tr = trs.get(0);
                ZtProject ztProject = new ZtProject();
                ztProject.setId(Convert.toInt(tr.select(".c-id").text()));
                ztProject.setName(tr.select(".c-name").attr("title"));
                ztProject.setStatus(tr.select(".c-status").text());
                ztProject.setPm(tr.select(".c-PM").text());
                ztProject.setBudget(tr.select(".c-budget").text());
                ztProject.setBegin(tr.select(".c-begin").text());
                ztProject.setEnd(tr.select(".c-end").text());
                ztProject.setProgress(tr.select(".c-progress").text());
                response.setSuccess(true);
                response.setMessage("请求成功");
                response.setResult(ztProject);
                return response;
            }
            StaticLog.info(body);
            response.setMessage("无数据");
            return response;
        } catch (HttpException e) {
            StaticLog.error(e);
        }
        response.setSuccess(false);
        response.setMessage("请求失败");
        return response;
    }
}
